package com.zkadmin.renderer;

import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Selectbox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import com.zkadmin.constraints.EmailConstraint;
import com.zkadmin.constraints.MobileConstraint;
import com.zkadmin.controller.UserListCtrl;
import com.zkadmin.entity.SysUser;
import com.zkadmin.service.SysUserService;
import com.zkadmin.util.AdminConstants;
import com.zkadmin.util.AdminWebUtils;
import com.zkadmin.util.DateTimeUtils;
import com.zkadmin.util.MsgBox;

public class SysUserListRenderer extends BaseRenderer implements ListitemRenderer<SysUser> {
	private SysUserService sysUserService;
	private UserListCtrl userListCtrl;
	private Window win;

	public SysUserListRenderer(Window win, UserListCtrl userListCtrl, SysUserService sysUserService) {
		this.sysUserService = sysUserService;
		this.userListCtrl = userListCtrl;
		this.win = win;
	}

	@Override
	public void render(Listitem listitem, final SysUser user, int index) throws Exception {
		String lockLabel = user.getLocked() ? "锁定" : "正常";
		if (SecurityUtils.getSubject().hasRole(AdminConstants.ROLE_ADMIN) || SecurityUtils.getSubject().isPermitted("sys:user:update")) {
			final Textbox usernameBox = new Textbox(user.getUsername());
			usernameBox.setInplace(true);
			usernameBox.setWidth("90%");
			usernameBox.setMaxlength(12);
			createListcell(listitem).appendChild(usernameBox);
			usernameBox.setConstraint("no empty");
			usernameBox.addEventListener(Events.ON_CHANGE, new EventListener<Event>() {
				@Override
				public void onEvent(Event event) throws Exception {
					SysUser nuser = sysUserService.findByUsername(usernameBox.getText());
					if (nuser != null) {
						MsgBox.alert("【" + usernameBox.getText() + "】这个帐户已经存在。");
						userListCtrl.refreshData();
						return;
					}
					user.setUsername(usernameBox.getText());
					saveAndRefresh(user);
				}
			});

			final Textbox nameBox = new Textbox(user.getName());
			nameBox.setInplace(true);
			nameBox.setWidth("90%");
			nameBox.setMaxlength(15);
			createListcell(listitem).appendChild(nameBox);
			nameBox.setConstraint("no empty");
			nameBox.addEventListener(Events.ON_CHANGE, new EventListener<Event>() {
				@Override
				public void onEvent(Event event) throws Exception {
					SysUser nuser = sysUserService.findByName(nameBox.getText());
					if (nuser != null && nuser != user) {
						MsgBox.alert("【" + nameBox.getText() + "】这个姓名或昵称已经存在。");
						userListCtrl.refreshData();
						return;
					}

					user.setName(nameBox.getText());
					saveAndRefresh(user);
				}
			});

			final Textbox emailBox = new Textbox(user.getEmail());
			emailBox.setInplace(true);
			emailBox.setWidth("90%");
			emailBox.setMaxlength(30);
			emailBox.setConstraint(new EmailConstraint());
			createListcell(listitem).appendChild(emailBox);
			emailBox.addEventListener(Events.ON_CHANGE, new EventListener<Event>() {
				@Override
				public void onEvent(Event event) throws Exception {
					user.setEmail(emailBox.getText());
					saveAndRefresh(user);
				}
			});

			final Textbox mobileBox = new Textbox(user.getMobile());
			mobileBox.setInplace(true);
			mobileBox.setWidth("90%");
			mobileBox.setMaxlength(11);
			mobileBox.setConstraint(new MobileConstraint());
			createListcell(listitem).appendChild(mobileBox);
			mobileBox.addEventListener(Events.ON_CHANGE, new EventListener<Event>() {
				@Override
				public void onEvent(Event event) throws Exception {
					user.setMobile(mobileBox.getText());
					saveAndRefresh(user);
				}
			});

			final Selectbox lockedBox = new Selectbox();
			lockedBox.setWidth("90%");
			ListModelList<String> lockItems = new ListModelList<String>(new String[] { "正常", "锁定" });
			lockedBox.setModel(lockItems);
			lockItems.addToSelection(lockLabel);
			createListcell(listitem).appendChild(lockedBox);
			if (user.getId() > 1) {
				lockedBox.addEventListener(Events.ON_SELECT, new EventListener<Event>() {
					@Override
					public void onEvent(Event event) throws Exception {
						user.setLocked(lockedBox.getSelectedIndex() != 0);
						saveAndRefresh(user);
					}
				});
			}

			lockedBox.setDisabled(user.getId() == 1);
		} else {
			createListcell(listitem).setLabel(user.getUsername());
			createListcell(listitem).setLabel(user.getName());
			createListcell(listitem).setLabel(user.getEmail());
			createListcell(listitem).setLabel(user.getMobile());
			createListcell(listitem).setLabel(lockLabel);
		}

		createListcell(listitem).setLabel(DateTimeUtils.fmt(user.getLastLoginedAt()));

		Hbox hbox = createHbox(listitem);
		Button roleBtn = new Button("分配角色");
		if (!SecurityUtils.getSubject().hasRole(AdminConstants.ROLE_ADMIN)) {
			roleBtn.setVisible(SecurityUtils.getSubject().isPermitted("sys:user:role"));
		}

		roleBtn.setIconSclass("z-icon-check-square-o");
		hbox.appendChild(roleBtn);
		roleBtn.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				Map<String, Object> args = new HashMap<String, Object>();
				args.put("userId", user.getId());
				Window window = (Window) Executions.createComponents(AdminWebUtils.getZulPagePath("admin/user_role_dialog.zul"), win, args);
				window.addEventListener(AdminConstants.EVENT_ONREFRESH, new EventListener<Event>() {
					@Override
					public void onEvent(Event event) throws Exception {
						userListCtrl.refreshData();
					}
				});
				window.doModal();
			}
		});

		Button resetPwdBtn = new Button("重置密码");
		if (!SecurityUtils.getSubject().hasRole(AdminConstants.ROLE_ADMIN)) {
			resetPwdBtn.setVisible(SecurityUtils.getSubject().isPermitted("sys:user:reset_pwd"));
		}
		resetPwdBtn.setIconSclass("z-icon-key");
		hbox.appendChild(resetPwdBtn);
		resetPwdBtn.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				Map<String, Object> args = new HashMap<String, Object>();
				args.put("userId", user.getId());
				Window window = (Window) Executions.createComponents(AdminWebUtils.getZulPagePath("admin/reset_user_pwd_dialog.zul"), win, args);
				window.doModal();
			}
		});

		Button delBtn = new Button("删除");
		if (!SecurityUtils.getSubject().hasRole(AdminConstants.ROLE_ADMIN)) {
			delBtn.setVisible(SecurityUtils.getSubject().isPermitted("sys:user:delete"));
		}
		if (1 == user.getId() || user.getUsername().equals(SecurityUtils.getSubject().getPrincipal().toString())) {
			delBtn.setVisible(false);
		}
		delBtn.setIconSclass("z-icon-times");
		hbox.appendChild(delBtn);
		delBtn.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				Messagebox.show("是否删除用户？", "删除确认", Messagebox.YES | Messagebox.NO, Messagebox.QUESTION, new EventListener<Event>() {
					@Override
					public void onEvent(Event event) throws Exception {
						if (Messagebox.ON_YES.equals(event.getName())) {
							sysUserService.delete(user.getId());
							userListCtrl.refreshData();
						}

					}
				});
			}
		});
	}

	private void saveAndRefresh(final SysUser user) {
		try {
			sysUserService.save(user);
		} catch (ObjectOptimisticLockingFailureException e) {
			MsgBox.alert(AdminConstants.getErrorDataVersionMessage());
		} finally {
			userListCtrl.refreshData();
		}
	}
}
